/*!
* @Author: luoob
* @Date: 2021-04-14 20:11:00
* @Last Modified by: leo
* @Last Modified time: 2020-04-14 20:11:00
* @Instruduction: 文件增强类
*/

import _ from 'lodash'
import { Option } from 'src/types/filePlus'

const typeMap = new Map([
    ['image', ['image/png', 'image/jpg', 'image/jpeg']]
])

type FileOption = Option & { type?: 'image' }

class FilePlus {
    private file: any = ''
    private option: FileOption = {}

    private customTypeValidateFn: Function | undefined
    constructor(file: any, option: FileOption) {
        try {
            if (!file || !option) {
                throw new Error('except file and option')
            }
            const { customSuffix, customTypes } = option
            if (customSuffix && customTypes) {
                throw new Error('customSuffix and customTypes only support use one')
            }
            this.file = file
            this.option = option
        } catch (error) {
            console.error(error.message)
        }
    }

    /**
     * 是否文件类型错误
     * @date 2021-04-13
     * @returns {boolean}
     */
    get hasTypeError() {
        let fileType = this.file.type
        // 使用自定义的校验函数
        if (this.customTypeValidateFn) {
            return !this.customTypeValidateFn!(fileType, this.file)
        }
        const { type, customTypes } = this.option
        let types
        // customTypes 存在时，忽略 type
        if (customTypes) {
            if (!_.isArray(customTypes)) {
                return console.error('customTypes expect array')
            }
            types = customTypes
        } else if (!type) {
            return console.error('not pass type field')
        } else {
            if (!this.option.type) {
                return console.error('please set file type in option or custom validate function')
            }
            types = typeMap.get(this.option!.type) || []
        }
        fileType = fileType.toLowerCase()
        return !types.includes(fileType)
    }

    /**
     * 是否文件大小错误(超过预期大小)
     * @date 2021-04-13
     * @returns {boolean}
     */
    get hasSizeError() {
        const { size } = this.option
        // 没有传入 size 属性
        if (!size) return console.error('not pass size field')
        // size 不是 number 类型
        if (!isNaN(size) && !_.isNumber(size)) {
            return console.error('size field expect number')
        }
        return this.file.size > size
    }

    /**
     * 获取临时图片链接
     * @date 2021-04-13
     * @returns {string}
     */
    public getImageTempUrl() {
        // 只支持图片文件
        const isTypeError = this.hasTypeError
        if (this.option.type !== 'image' || isTypeError) {
            return console.error('only support image file, but the file is not image file')
        }
        return URL.createObjectURL(this.file)
    }

    /**
     * 注册自定义校验文件类型函数
     * @date 2021-04-14
     * @returns {any}
     */
    public registerTypeCheck(fn: Function) {
        if (!_.isFunction(fn)) {
            return console.error('registerTypeCheck expect a function')
        }
        this.customTypeValidateFn = fn
    }
}

export default FilePlus
